"""
统一异常处理体系
提供标准化的异常类和全局错误处理机制
"""

from typing import Dict, Any, Optional
from fastapi import HTTPException, Request, status
from fastapi.responses import JSONResponse
from pydantic import BaseModel


class BaseAppException(Exception):
    """基础应用异常类"""
    def __init__(self, 
                 message: str, 
                 code: str = "INTERNAL_ERROR",
                 status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR,
                 details: Optional[Dict[str, Any]] = None):
        super().__init__(message)
        self.message = message
        self.code = code
        self.status_code = status_code
        self.details = details or {}


class ValidationError(BaseAppException):
    """参数验证错误"""
    def __init__(self, message: str, field: Optional[str] = None):
        details = {"field": field} if field else {}
        super().__init__(
            message=message,
            code="VALIDATION_ERROR",
            status_code=status.HTTP_400_BAD_REQUEST,
            details=details
        )


class AuthenticationError(BaseAppException):
    """认证错误"""
    def __init__(self, message: str = "认证失败"):
        super().__init__(
            message=message,
            code="AUTHENTICATION_ERROR",
            status_code=status.HTTP_401_UNAUTHORIZED
        )


class AuthorizationError(BaseAppException):
    """授权错误"""
    def __init__(self, message: str = "权限不足"):
        super().__init__(
            message=message,
            code="AUTHORIZATION_ERROR",
            status_code=status.HTTP_403_FORBIDDEN
        )


class NotFoundError(BaseAppException):
    """资源未找到错误"""
    def __init__(self, resource_type: str, resource_id: str):
        super().__init__(
            message=f"{resource_type} '{resource_id}' 未找到",
            code="NOT_FOUND_ERROR",
            status_code=status.HTTP_404_NOT_FOUND,
            details={"resource_type": resource_type, "resource_id": resource_id}
        )


class DatabaseError(BaseAppException):
    """数据库操作错误"""
    def __init__(self, message: str, operation: Optional[str] = None, query: Optional[str] = None):
        details = {}
        if operation:
            details["operation"] = operation
        if query:
            details["query"] = query
            
        super().__init__(
            message=f"数据库错误: {message}",
            code="DATABASE_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details=details
        )


class ServiceError(BaseAppException):
    """服务错误"""
    def __init__(self, service_name: str, message: str):
        super().__init__(
            message=f"{service_name} 服务错误: {message}",
            code="SERVICE_ERROR",
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            details={"service_name": service_name}
        )


class RateLimitError(BaseAppException):
    """速率限制错误"""
    def __init__(self, limit: int, window: str):
        super().__init__(
            message=f"速率限制超出: {limit} 次/{window}",
            code="RATE_LIMIT_EXCEEDED",
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            details={"limit": limit, "window": window}
        )


class ConfigurationError(BaseAppException):
    """配置错误"""
    def __init__(self, config_key: str, message: str):
        super().__init__(
            message=f"配置错误 [{config_key}]: {message}",
            code="CONFIGURATION_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            details={"config_key": config_key}
        )


class ExternalServiceError(BaseAppException):
    """外部服务错误"""
    def __init__(self, service_name: str, message: str):
        super().__init__(
            message=f"外部服务 {service_name} 错误: {message}",
            code="EXTERNAL_SERVICE_ERROR",
            status_code=status.HTTP_502_BAD_GATEWAY,
            details={"service_name": service_name}
        )


# 错误响应模型
class ErrorResponse(BaseModel):
    """标准化错误响应模型"""
    error: bool = True
    code: str
    message: str
    details: Optional[Dict[str, Any]] = None


def create_error_response(exception: BaseAppException) -> ErrorResponse:
    """创建标准化的错误响应"""
    return ErrorResponse(
        code=exception.code,
        message=exception.message,
        details=exception.details
    )


async def http_exception_handler(request, exc: Exception):
    """处理FastAPI HTTP异常"""
    # 确保传入的是HTTPException
    if not isinstance(exc, HTTPException):
        exception = BaseAppException(
            message=str(exc),
            code="HTTP_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
        )
    else:
        exception = BaseAppException(
            message=exc.detail,
            code="HTTP_ERROR",
            status_code=exc.status_code
        )
        
    error_response = create_error_response(exception)
    return JSONResponse(
        status_code=exception.status_code,
        content=error_response.model_dump()
    )


async def base_app_exception_handler(request: Request, exc: Exception):
    """处理基础应用异常"""
    # 确保传入的是BaseAppException或其子类
    if not isinstance(exc, BaseAppException):
        # 如果不是，创建一个通用的BaseAppException
        exc = BaseAppException(
            message=str(exc),
            code="UNEXPECTED_ERROR",
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
        )
    
    error_response = create_error_response(exc)
    return JSONResponse(
        status_code=exc.status_code,
        content=error_response.model_dump()
    )


# 保持向后兼容的异常类（逐步迁移）
class ResearchException(BaseAppException):
    """向后兼容的研究异常类"""
    def __init__(self, message: str, code: str = "INTERNAL_ERROR"):
        super().__init__(message=message, code=code)


class UserNotFoundError(NotFoundError):
    """用户不存在异常"""
    def __init__(self, user_id: str):
        super().__init__(resource_type="用户", resource_id=user_id)


class SessionNotFoundError(NotFoundError):
    """会话不存在异常"""
    def __init__(self, session_id: str):
        super().__init__(resource_type="会话", resource_id=session_id)


class APIValidationError(ValidationError):
    """API参数验证错误"""
    def __init__(self, field: str, message: str):
        super().__init__(message=f"参数验证失败: {field} - {message}", field=field)


class WorkflowExecutionError(ServiceError):
    """工作流执行错误"""
    def __init__(self, step: str, error: str):
        super().__init__(service_name="工作流", message=f"[{step}]: {error}")


class ServiceUnavailableError(ServiceError):
    """服务不可用错误"""
    def __init__(self, service_name: str):
        super().__init__(service_name=service_name, message="服务不可用")


class RateLimitExceededError(RateLimitError):
    """速率限制超出错误"""
    def __init__(self, limit: int, window: str):
        super().__init__(limit=limit, window=window)
